#include "NestAgent.h"

//Constructor
NestAgent::NestAgent(std::string name)
	: Agent(name) 
{
	ccTimer = new CallCameraTimer(this);
	pnTimer = new PurgeNestTimer(this);
	state = None;
	partType = EMPTY;
	testing=false;
	purging = false;
	testing = false;
	numberOfCameraCalls = 0;
}

//Messages

//From Lane
void NestAgent::msgIThinkYoureFull() {
	print("Received msgIThinkYoureFull from LaneAgent");
	numberOfCameraCalls++;
	state = PossiblyFull;
	stateChanged();
}

//From Camera
void NestAgent::msgHereIsAPicture(Picture p) {
	//schedule something 
	print("Received msgHereIsAPicture from CameraAgent");
	if( p == Stable) {
		state = GoodPicture;
	} else if (p == Unstable) {
		if(testing == false) {
			ccTimer->start();
		}
		state = None;
	} else {
		state = BadPicture;
	}
	stateChanged();
}

//From PartRobot
void NestAgent::msgPartWasTaken() {
	print("Received msgPartWasTaken from PartRobot");
	if(testing == false) {
		ccTimer->start();
	}
}

//From PartRobot
void NestAgent::msgPleaseGetParts(PartType p) {
	print("Received msgPleaseGetParts from PartRobotAgent");
	if(p != partType) {
		partType = p;
		state = Ready_To_Purge;
	} else {
		state = Request_New_Parts;
	}
	stateChanged();
}

//From Lane
void NestAgent::msgPleaseStopPurging() {
	print("Received msgPleaseStopPurging from LaneAgent");
	tellGUIToPurge(false);
	state = None;
	stateChanged();
}

//Scheduler
bool NestAgent::pickAndExecuteAnAction() {
	if(state == Ready_To_Purge) {
		if(testing == false) {
			ccTimer->start();
			ccTimer->stop();			
		}
		tellGUIToPurge(true);
		givePartTypeToLane();
		state = Purging;
		return true;
	}

	if(state == Request_New_Parts) {
		givePartTypeToLane();
		state = None;
		return true;
	}

	if(state == PossiblyFull) {
		tellCameraIThinkImFull();
		state = None;
		return true;
	}
	
	if(state == GoodPicture) {
		tellPartRobotImStable();
		state = None;
		return true;
	}

	if(state == BadPicture) {
		tellGUIToPurge(true);
		if(testing == false) {
			pnTimer->start();
		}
		state = Purging;
		return true;
	}
	return false;
}

//Actions
//To PartRobot
void NestAgent::tellPartRobotImStable() {
	partsRobot->msgImStable(this);
}

//To Lane
void NestAgent::givePartTypeToLane() {
	lane->msgPleaseGetParts(partType);
}

//To Camera
void NestAgent::tellCameraIThinkImFull() {
	camera->msgIThinkImFull(partType);
}

//To Camera
void NestAgent::tellCameraIThinkImFullTimer() {
	if(testing == false) {
		ccTimer->stop();
	}
	tellCameraIThinkImFull();
}

void NestAgent::reactToPossibleLaneJam(bool flag) {
	if(flag == true) {
		lane->msgYourSpeedNeedsToChange(lane->getSpeed() + 1);	
	} else if(lane->getSpeed() != 1) {
		lane->msgYourSpeedNeedsToChange(1);
	}
	numberOfCameraCalls = 0;
}

//To GUI
void NestAgent::tellGUIToStart() {
	guiNest->Start();
}

//To GUI
void NestAgent::tellGUIToPurge(bool flag) {
	purging = flag;
	guiNest->setPurge(flag);
}

//To GUI
void NestAgent::tellGUIToStop() {
	guiNest->Stop();
}

void NestAgent::handleBreak() {
	((GUINest*)guiNest)->DoBreak();
}

void NestAgent::handleFix() {
	((GUINest*)guiNest)->DoFix();
}

//Assessors

void NestAgent::setPartRobot(PartRobot* robot) {
	partsRobot = robot;
}

void NestAgent::setCamera(Camera* ca) {
	camera = ca;
}

void NestAgent::setLane(Lane* la) {
	lane = la;
}

void NestAgent::setGUI(GUINestInterface* gui) {
	guiNest = gui;
	tellGUIToStart();
}

GUINest* NestAgent::getGUI() {
	return (GUINest*)guiNest;
}

